package merger;

import static com.lemon.ai.socket.packets.spiritgame.db.utils.Mapping.toTableName;

import java.io.File;
import java.lang.reflect.Method;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import com.lemon.ai.socket.packets.spiritgame.db.dao.BagDAO;
import com.lemon.ai.socket.packets.spiritgame.db.dao.FlowerDAO;
import com.lemon.ai.socket.packets.spiritgame.db.dao.PersonDAO;
import com.lemon.ai.socket.packets.spiritgame.db.dao.RelationDAO;
import com.lemon.ai.socket.packets.spiritgame.db.dao.factory.DaoFactory;
import com.lemon.ai.socket.packets.spiritgame.db.domain.Bag;
import com.lemon.ai.socket.packets.spiritgame.db.domain.Flower;
import com.lemon.ai.socket.packets.spiritgame.db.domain.Person;
import com.lemon.ai.socket.packets.spiritgame.db.domain.Relation;
import com.lemon.ai.socket.packets.spiritgame.db.utils.DbUtils;
import com.lemon.ai.socket.packets.spiritgame.db.utils.Mapping;


/**
 * 包含一个数据库的所有数据
 * @author 	林岑
 * @time	2012年9月5日 17:44:44
 */
public class Datas {

	private static final DaoFactory d = DaoFactory.getInstance();

	/**
	 * 所有数据表对应的对象
	 * 键: 表名, 值:表对应的所有对象
	 */
	final Map<String, List<?>> all = new HashMap<String, List<?>>();

	private Datas(String path, String uname, String pass) {
		DbUtils.changeTo(path, uname, pass);//将数据库连接切换到指定路径
		loadAll();
		DbUtils.changeBack();
	}

	/**
	 * 复制构造
	 * @param dat
	 */
	public Datas(Datas dat) {
		this.all.putAll(dat.all);
	}
	
	/**
	 * 读取一个数据库
	 * @param path
	 * @param uname
	 * @param pass
	 * @return
	 */
	public static Datas load(String path, String uname, String pass) {
		return new Datas(path, uname, pass);
	}
	
	/**
	 * 读取数据库所有资料
	 */
	private void loadAll() {

		try {
			File f = new File("src\\com\\lemon\\ai\\socket\\packets\\spiritgame\\db\\dao\\Impl");
			int i = 0;
			for (File ff : f.listFiles()) {
				Class.forName("com.lemon.ai.socket.packets.spiritgame.db.dao.Impl." + ff.getName().replaceAll(".java", ""));
				i++;
			}

			{
				BagDAO bd = d.getBagDAO();
				List<Bag> bs = bd.getAll();
				all.put(toTableName(Bag.class), bs);
				i--;
			}

			{
				FlowerDAO fd = d.getFlowerDAO();
				List<Flower> sf = fd.getAll();
				all.put(toTableName(Flower.class), sf);
				i--;
			}

			{
				PersonDAO pd = d.getPersonDAO();
				List<Person> ps = pd.getAll();
				all.put(toTableName(Person.class), ps);
				i--;
			}

			{
				RelationDAO rd = d.getRelationDAO();
				List<Relation> rs = rd.getAll();
				all.put(toTableName(Relation.class), rs);
				i--;
			}

			if(i != 0)
				throw new RuntimeException("数据表有遗漏");

		} catch (Exception e) {
			e.printStackTrace();
		}
	}


	/**
	 * 将该数据集中的信息全部写入指定数据库
	 * @param path
	 * @param uname
	 * @param pass
	 */
	public void write(String path, String uname, String pass) {
		DbUtils.changeTo(path, uname, pass);
		try {
			int i = 0;
			for (String tableName : all.keySet()) {
				List<?> list = all.get(tableName);
				Class<?> c = Mapping.getDAOImplClass(tableName);
				
				int j = 0;
				Object ins = c.newInstance();
				for (Object o : list) {
					System.out.println("正在写入数据库:	" + (i + 1) + "/" + all.keySet().size() + "	" + (j + 1) + "/" + list.size());
					Method m = c.getMethods()[2];
					m.invoke(ins, o);
					j++;
				}
				i++;
			}
			System.out.println("写入完毕");
		} catch (Exception e) {
			e.printStackTrace();
		}
		DbUtils.changeBack();
	}

	/**
	 * 将该数据库中的数据, 全部合并到des中...
	 * @param des
	 */
	@SuppressWarnings({ "rawtypes", "unchecked" })
	public void mergeTo(Datas des) {
		for (String k : Mapping.getAllTableName()) {
			List<?> l1 = des.all.get(k);
			List l2 = this.all.get(k);
			if(l2 != null ) {
				if(l1 != null) {
					l1.addAll(l2);
				} else {
					des.all.put(k, l2);
				}
			}
		}
	}

}
